/* 
 *  <copyright file="TextureManagerGameService.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SobrietyEngine.Logging;

namespace SobrietyEngine.Assets.Textures
{
    public class TextureManagerGameService:GameComponent, ITextureManagerGameService
    {
        class TMTexture
        {
            public TMTexture(String name, Texture2D texture, Boolean loaded)
            {
                _loaded = loaded;
                _assetName = name;
                _texture =texture;
            }
            Boolean _loaded;
            public Boolean Loaded { get { return _loaded; } set { _loaded = value; } }

            String _assetName;
            public String AssetName { get { return _assetName; } set { _assetName= value; } }

            Texture2D _texture;
            public Texture2D Texture { get { return _texture; } set { _texture = value; } }
        }

        Dictionary<String, TMTexture> textureMap;
        Dictionary<String, AnimationData> animationMap = new Dictionary<string,AnimationData>();

        public Texture2D this[String index]
        {
            set
            {
                LoadTexture(index); 
            }
            get
            {
                return LoadTexture(index);
            }
        }

        IAssetGameService assetGameService;

        public TextureManagerGameService(Game game)
            : base(game)
        {
            textureMap = new Dictionary<string, TMTexture>();

            game.Services.AddService(typeof(ITextureManagerGameService), this);
        }

        public override void Initialize()
        {
            assetGameService = ((SobrietyEngine.Games.SobrietyGame)Game).AssetGameService;
            base.Initialize();
        }

        public Texture2D LoadTexture(String textureName)
        {
            if (textureMap.ContainsKey(textureName))
            {
                if (textureMap[textureName].Loaded == true)
                    return textureMap[textureName].Texture;
                textureMap[textureName].Texture = assetGameService.Load<Texture2D>(textureName);
                textureMap[textureName].Loaded = true;
                return textureMap[textureName].Texture;

            }
            try
            {
                textureMap.Add(textureName, new TMTexture(textureName, assetGameService.Load<Texture2D>(textureName), true));
            }
            catch (Exception ex)
            {
                textureMap.Add(textureName, new TMTexture(textureName, assetGameService.Load<Texture2D>("Textures/Missing"), true));
                SobrietyEngine.Logging.Logger.GetSingleton().WriteError("TextureManagerGameService::LoadTexture()::Missing '" + textureName + "'" + ex.Message);
            }
            return textureMap[textureName].Texture;
        }

        public void LoadAnimation(String assetName)
        {
            //load an animation asset from an xml file with the 'assetName'
            //AnimationData ad = assetGameService.Load<AnimationData>(assetName);

            //AnimationData animDat = new AnimationData(ad);
            String data = assetGameService.Load<String>(assetName);
            AnimationData animDat = AnimationSetReader.Load(data);

            if (animationMap.ContainsKey(animDat.AnimationSetName))
            {
                Logger.GetSingleton().WriteDebug("TextureManagerGameService::LoadAnimation()::Animation already loaded! '" + assetName + "'");
            }
            else
                animationMap.Add(animDat.AnimationSetName, animDat);
        }
        
        public void LoadAnimations(String animListAssetName)
        {
            //load a list of animations from an XML asset that list the animation assets
            throw new Exception("Load animations not implemented");
        }

        public AnimationData GetAnimation(String name)
        {
            if (animationMap.ContainsKey(name))
                return animationMap[name];
            else
            {
                LoadAnimation(name);
                
                if (animationMap.ContainsKey(name))
                    return animationMap[name];
                else
                {
                    Logger.GetSingleton().WriteError("Animation not found " + name);
                    return null;
                }
            }
        }

        public void LoadAnimationTextures(String name)
        {
            if (!animationMap.ContainsKey(name))
                Logger.GetSingleton().WriteError("Animation not found " + name);

            foreach (String key in animationMap[name].Animations.Keys)
            {
                foreach (FrameData fd2 in animationMap[name].Animations[key])
                {
                    fd2.Texture = LoadTexture(fd2.TextureName);
                }
            }
        }
    }
}